/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2016-2019, LomboTech Co.Ltd.
 * Author: lomboswer <lomboswer@lombotech.com>
 *
 * csp_memctrl.h - memctrl csp head file
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#ifndef __CSP_MEMCTRL_H__
#define __CSP_MEMCTRL_H__

#include <linux/types.h>
#include <mach/csp.h>

#define MEMCTRL_AXI_RQOS0_OFFSET		0x9400
#define MEMCTRL_AXI_WQOS0_OFFSET		0x9404

#define MEMCRTL_VER_OFFSET			0x00000000
#define MEMCRTL_MON_MODE_CTRL_OFFSET		0x00000004
#define MEMCRTL_BW_CTRL_OFFSET			0x00000008
#define MEMCRTL_INT_EN_OFFSET			0x0000000C
#define MEMCRTL_UNITS_CFG_OFFSET		0x00000010
#define MEMCRTL_MON_STATUS_OFFSET		0x00000014
#define MEMCRTL_BW_STM_OFFSET			0x00000018
#define MEMCRTL_RD_LAT_OF_OFFSET		0x00000020
#define MEMCRTL_WR_LAT_OF_OFFSET		0x00000024
#define MEMCRTL_TOTAL_DAT_OFFSET		0x00000040
#define MEMCRTL_TOTAL_RDAT_OFFSET		0x00000044
#define MEMCRTL_TOTAL_WDAT_OFFSET		0x00000048
#define MEMCRTL_TOTAL_RPDAT_OFFSET		0x00000050
#define MEMCRTL_TOTAL_WPDAT_OFFSET		0x00000054

#define MEMCRTL_RD_DAT_OFFSET			0x00000080
#define MEMCRTL_WR_DAT_OFFSET			0x00000084
#define MEMCRTL_RD_DAT_PEAK_OFFSET		0x00000088
#define MEMCRTL_WR_DAT_PEAK_OFFSET		0x0000008C

#define MEMCRTL_RD_CMD_NUM_OFFSET		0x00000200
#define MEMCRTL_RD_LATENCY_OFFSET		0x00000204
#define MEMCRTL_WR_CMD_NUM_OFFSET		0x00000208
#define MEMCRTL_WR_LATENCY_OFFSET		0x0000020C

#define MEMCTRL_NOC_W_BWC0_OFFSET		0x00000800
#define MEMCTRL_NOC_W_BWC1_OFFSET		0x00000804
#define MEMCTRL_NOC_W_BWC2_OFFSET		0x00000808
#define MEMCTRL_NOC_W_BWC3_OFFSET		0x0000080C
#define MEMCTRL_NOC_R_BWC0_OFFSET		0x00000810
#define MEMCTRL_NOC_R_BWC1_OFFSET		0x00000814
#define MEMCTRL_NOC_R_BWC2_OFFSET		0x00000818
#define MEMCTRL_NOC_R_BWC3_OFFSET		0x0000081C

#define MEMCTRL_SARB_W_BWC0_OFFSET		0x00000100
#define MEMCTRL_SARB_W_BWC1_OFFSET		0x00000104
#define MEMCTRL_SARB_W_BWC2_OFFSET		0x00000108
#define MEMCTRL_SARB_W_BWC3_OFFSET		0x0000010C
#define MEMCTRL_SARB_R_BWC0_OFFSET		0x00000110
#define MEMCTRL_SARB_R_BWC1_OFFSET		0x00000114
#define MEMCTRL_SARB_R_BWC2_OFFSET		0x00000118
#define MEMCTRL_SARB_R_BWC3_OFFSET		0x0000011C

#define MEMCTRL_MASTER_OFFSET			0x10
#define MEMCTRL_MASTER_BW_OFFSET		0x20

#define MASK(width)				((1 << (width)) - 1)
#define GET(val, shift, width)		(((val) >> (shift)) & MASK(width))
#define DDR_BIT_WIDTH(val)			GET(val, 12, 2)

enum memctrl_clk_src {
	MEMCTRL_CLK_DISABLE = 0,
	MEMCTRL_CLK_24M,
	MEMCTRL_CLK_RSVD
};

enum memctrl_sample {
	MEMCTRL_SAMPLE_1MS = 0,
	MEMCTRL_SAMPLE_10MS,
	MEMCTRL_SAMPLE_100MS,
	MEMCTRL_SAMPLE_1S,
	MEMCTRL_SAMPLE_10S
};

enum memctrl_data_unit {
	MEMCTRL_UNIT_1B = 0,
	MEMCTRL_UNIT_16B,
	MEMCTRL_UNIT_64B,
	MEMCTRL_UNIT_256B,
	MEMCTRL_UNIT_1KB,
	MEMCTRL_UNIT_4KB,
	MEMCTRL_UNIT_64KB,
	MEMCTRL_UNIT_128KB,
};

enum memctrl_bw_ctrl_mode {
	MEMCTRL_NOT_LIMIT_MODE = 0,
	MEMCTRL_RANDOM_MODE,
	MEMCTRL_PEEK_LIMIT_MODE,
	MEMCTRL_AVERAGE_MODE,
};

enum memctrl_bw_random_mode {
	MEMCTRL_RANDOM_MODE1 = 0,
	MEMCTRL_RANDOM_MODE2,
	MEMCTRL_RANDOM_MODE3,
	MEMCTRL_RANDOM_MODE4,
};

enum memctrl_rw {
	W = 0,
	R,
};

enum memctrl_channel_id {
	MEMCTRL_CPU = 0,
	MEMCTRL_MPEG,
	MEMCTRL_AX0,
	MEMCTRL_VISS,
	/* MEMCTRL_VISS1, reserved */

	MEMCTRL_DPU = 5,
	MEMCTRL_DMA,
	/* MEMCTRL_VDC, reserved */

	MEMCTRL_GMAC0 = 8,
	MEMCTRL_VGSS,
	MEMCTRL_IVX,
	/* MEMCTRL_GPU, reserved */
	/* MEMCTRL_GMAC1, reserved */

	MEMCTRL_CE = 13,
	/* MEMCTRL_AX1, reserved */
	MEMCTRL_HVC = 15,
	/* MEMCTRL_USB3_0, reserved */
	/* MEMCTRL_USB3_1, reserved */
	/* MEMCTRL_USB2, not support(hclk) */
	/* MEMCTRL_SDC0, not support(hclk) */
	/* MEMCTRL_SDC1, not support(hclk) */
	/* MEMCTRL_AMU, not support(hclk) */
	/* MEMCTRL_SDC2, not support(hclk) */

	MEMCTRL_I2C4 = 23,
	MEMCRTL_MAX
};

void csp_memctrl_set_mode(void *base, bool manual);
void csp_memctrl_enable(void *base, bool enable);
void csp_memctrl_interrupt_enable(void *base, bool enable);
void csp_memctrl_set_clk(void *base, enum memctrl_clk_src clk_sel);
void csp_memctrl_set_sample(void *base, enum memctrl_sample sample);
void csp_memctrl_set_data_unit(void *base, enum memctrl_data_unit data);
u32 csp_memctrl_is_data_overflow(void *base);
u32 csp_memctrl_is_cycle_overflow(void *base);
void csp_memctrl_clear_status(void *base);
u32 csp_memctrl_get_rd_latency_status(void *base);
void csp_memctrl_clear_rd_latency_status(void *base);
u32 csp_memctrl_get_wr_latency_status(void *base);
void csp_memctrl_clear_wr_latency_status(void *base);
u32 csp_memctrl_get_cycle(void *base);
u32 csp_memctrl_get_total_data_size(void *base);
u32 csp_memctrl_get_total_rd_data_size(void *base);
u32 csp_memctrl_get_total_wr_data_size(void *base);
u32 csp_memctrl_get_total_rd_peak(void *base);
u32 csp_memctrl_get_total_wr_peak(void *base);
u32 csp_memctrl_get_rd_data_size(void *base, int channel);
u32 csp_memctrl_get_wr_data_size(void *base, int channel);
u32 csp_memctrl_get_rd_peak_data_size(void *base, int channel);
u32 csp_memctrl_get_wr_peak_data_size(void *base, int channel);
u32 csp_memctrl_get_rd_cmd_num(void *base, int channel);
u32 csp_memctrl_get_rd_latency(void *base, int channel);
u32 csp_memctrl_get_wr_cmd_num(void *base, int channel);
u32 csp_memctrl_get_wr_latency(void *base, int channel);
void csp_memctrl_start_hvc(u32 enable);
u32 csp_memctrl_get_hvc_rd_data(void);
u32 csp_memctrl_get_hvc_wr_data(void);
u32 csp_ddr_get_bit_width(void *base);
void csp_memctrl_set_bw_timewin(void *base, u32 master, u32 cycle,
				enum memctrl_rw read, u32 arbiter);
u32 csp_memctrl_get_bw_timewin(void *base, u32 master, enum memctrl_rw read,
				u32 arbiter);
void csp_memctrl_set_bw_datasize(void *base, u32 master, u32 bandwidth,
				enum memctrl_rw read, u32 arbiter);
u32 csp_memctrl_get_bw_datasize(void *base, u32 master, enum memctrl_rw read,
				u32 arbiter);
void csp_memctrl_set_bw_ctrl_mode(void *base, u32 master,
				enum memctrl_bw_ctrl_mode mode,
				enum memctrl_rw read, u32 arbiter);
u32 csp_memctrl_get_bw_ctrl_mode(void *base, u32 master, enum memctrl_rw read,
				u32 arbiter);
void csp_memctrl_set_bw_randomode(void *base, u32 master,
				enum memctrl_bw_random_mode mode,
				enum memctrl_rw read, u32 arbiter);
u32 csp_memctrl_get_bw_randomode(void *base, u32 master, enum memctrl_rw read,
				u32 arbiter);
void csp_memctrl_set_bw_seed(void *base, u32 master, u32 seed,
				enum memctrl_rw read, u32 arbiter);
u32 csp_memctrl_get_bw_seed(void *base, u32 master, enum memctrl_rw read,
				u32 arbiter);

#endif/* __CSP_MEMCTRL_H__ */
